package com.gzhryc.shared_device.oem.code.agent.services;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.data.TreeUtils;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.oem.code.agent.dao.AgentLevelMenuRelDao;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentMenu;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentLevelMenuRel;
import com.gzhryc.shared_device.oem.code.agent.dao.enums.AgentMenuEnum;
import com.gzhryc.system.dto.MenuData;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class AgentLevelMenuRelService {

    static Logger log = Logger.getLogger(AgentLevelMenuRelService.class);

    public static AgentLevelMenuRelService self() {
        return MultiDBTools.getService(AgentLevelMenuRelService.class, true);
    }

    public static AgentLevelMenuRelService self(String jdbcKey) {
        return MultiDBTools.getService(jdbcKey, AgentLevelMenuRelService.class, true);
    }

    AgentLevelMenuRelDao dao;

    public AgentLevelMenuRelService(String jdbcKey) {
        this.dao = new AgentLevelMenuRelDao(jdbcKey);
    }

    public List<AgentLevelMenuRel> findJoinByLevel(Integer level){
        if(level != null){
            Conditions conditions = new Conditions(AgentLevelMenuRel.class);
            conditions.and().is("level",level);

            try {
                return dao.findJoinByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public List<MenuData> findMenuDataByLevel(Integer level) {
        if(level != null) {
            List<AgentLevelMenuRel> agentMenuRelList = findJoinByLevel(level);
            if(agentMenuRelList != null && agentMenuRelList.size() > 0) {
                List<AgentMenu> agentMenus = new ArrayList<>();
                for(AgentLevelMenuRel agentMenuRel : agentMenuRelList){
                    agentMenus.add(agentMenuRel.getMenu());
                }
                List<MenuData> menuData = TreeUtils.byTree(agentMenus, new TreeUtils.ConvertListen<AgentMenu, MenuData>() {
                    public MenuData change(AgentMenu parent, AgentMenu obj) {
                        return ClassTools.copy(new MenuData(), obj);
                    }
                });
                return menuData;
            }
        }
        return null;
    }

    public AgentLevelMenuRel getByKeys(Integer level,Long menuId){
        if(level != null && menuId != null) {
            Conditions conditions = new Conditions(AgentLevelMenuRel.class);
            conditions.and().is("level", level);
            conditions.and().is("menuId", menuId);

            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public boolean save(Integer level,List<Map<String,Object>> menuList) throws LogicException {
        if(level != null && menuList != null && menuList.size() > 0) {
            JdbcSession.begin();
            try {
                if(deleteByLevel(level)) {
                    for (Map<String, Object> item : menuList) {
                        Long menuId = Long.valueOf(item.get("id").toString());
                        AgentLevelMenuRel agentMenuRel = new AgentLevelMenuRel();
                        agentMenuRel.setLevel(level);
                        agentMenuRel.setMenuId(menuId);
                        agentMenuRel.setCreateDate(new Date());
                        if (dao.insert(agentMenuRel) > 0) {
                            // 关联权限
                            List<AgentMenu> funMenuList = AgentMenuService.self().findByParentAndType(agentMenuRel.getMenuId(),
                                    AgentMenuEnum.Type.Fun.index());
                            if (funMenuList != null && funMenuList.size() > 0) {
                                for (AgentMenu menu : funMenuList) {
                                    agentMenuRel = new AgentLevelMenuRel();
                                    agentMenuRel.setLevel(level);
                                    agentMenuRel.setMenuId(menu.getId());
                                    agentMenuRel.setCreateDate(new Date());
                                    if (dao.insert(agentMenuRel) <= 0) {
                                        throw new LogicException("配置功能菜单" + menu.getName() + "失败");
                                    }
                                }
                            }
                            List<Map<String, Object>> children = (List<Map<String, Object>>)item.get("children");
                            if (children != null && children.size() > 0) {
                                if (!saveChild(level, children)) {
                                    throw new LogicException("配置[" + menuId + "]的子菜单失败");
                                }
                            }
                        } else {
                            throw new LogicException("配置[" + menuId + "]菜单失败");
                        }
                    }
                    JdbcSession.commit();
                    return true;
                }
            }catch (SQLException e){
                log.error(e.getMessage(),e);
            }finally {
                JdbcSession.end();
            }
        }
        return false;
    }

    private boolean saveChild(Integer level,List<Map<String,Object>> menuList) throws LogicException {
        if(level != null && menuList != null && menuList.size() > 0) {
            JdbcSession.begin();
            try {
                for (Map<String, Object> item : menuList) {
                    Long menuId = Long.valueOf(item.get("id").toString());
                    AgentLevelMenuRel agentMenuRel = new AgentLevelMenuRel();
                    agentMenuRel.setLevel(level);
                    agentMenuRel.setMenuId(menuId);
                    agentMenuRel.setCreateDate(new Date());
                    if (dao.insert(agentMenuRel) > 0) {
                        // 关联权限
                        List<AgentMenu> funMenuList = AgentMenuService.self().findByParentAndType(agentMenuRel.getMenuId(),
                                AgentMenuEnum.Type.Fun.index());
                        if (funMenuList != null && funMenuList.size() > 0) {
                            for (AgentMenu menu : funMenuList) {
                                agentMenuRel = new AgentLevelMenuRel();
                                agentMenuRel.setLevel(level);
                                agentMenuRel.setMenuId(menu.getId());
                                agentMenuRel.setCreateDate(new Date());
                                if (dao.insert(agentMenuRel) <= 0) {
                                    throw new LogicException("配置功能菜单" + menu.getName() + "失败");
                                }
                            }
                        }
                        List<Map<String, Object>> children = (List<Map<String, Object>>) item.get("children");
                        if (children != null && children.size() > 0) {
                            if (!save(level, children)) {
                                throw new LogicException("配置[" + menuId + "]的子菜单失败");
                            }
                        }
                    } else {
                        throw new LogicException("配置[" + menuId + "]菜单失败");
                    }
                }
                JdbcSession.commit();
                return true;
            }catch (SQLException e){
                log.error(e.getMessage(),e);
            }finally {
                JdbcSession.end();
            }
        }
        return false;
    }

    public boolean deleteByLevel(Integer level){
        if(level != null){
            Conditions conditions = new Conditions(AgentLevelMenuRel.class);
            conditions.and().is("level",level);

            try {
                return dao.deleteByCondition(conditions) >= 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }
}
